package com.yunke.service.impl;

import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yunke.common.exception.YunkeException;
import com.yunke.dto.chat.YunkeCheckUserInfoDto;
import com.yunke.dto.chat.YunkeSendMessageDto;
import com.yunke.entity.*;
import com.yunke.mapper.*;
import com.yunke.service.YunkeChatService;
import com.yunke.service.YunkeUserService;
import com.yunke.vo.chat.YunkeChatVo;
import com.yunke.vo.chat.YunkeMessageVo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import java.math.BigDecimal;
import java.util.*;

/**
 * 聊天通讯Service实现类
 * 
 * @author yunke
 * @since 1.0.0
 */
@Slf4j
@Service
public class YunkeChatServiceImpl extends ServiceImpl<YunkeUserChatMapper, YunkeUserChat> implements YunkeChatService {

    @Autowired
    private YunkeUserChatMapper userChatMapper;

    @Autowired
    private YunkeUserMessageMapper userMessageMapper;

    @Autowired
    private YunkeCheckUserMapper checkUserMapper;

    @Autowired
    private YunkeUserService userService;

    @Override
    public Page<YunkeChatVo> getChatList(Long current, Long size) {
        // 检查登录状态
        if (!StpUtil.isLogin()) {
            throw new YunkeException("请先登录");
        }

        Long currentUserId = StpUtil.getLoginIdAsLong();
        log.info("获取聊天列表，用户ID：{}", currentUserId);

        // 分页查询聊天列表
        Page<YunkeUserChat> page = new Page<>(current, size);
        LambdaQueryWrapper<YunkeUserChat> wrapper = new LambdaQueryWrapper<>();
        wrapper.and(w -> w.eq(YunkeUserChat::getUserAId, currentUserId)
                .or().eq(YunkeUserChat::getUserBId, currentUserId))
                .eq(YunkeUserChat::getStatus, 1)
                .orderByDesc(YunkeUserChat::getLastMessageTime);

        Page<YunkeUserChat> chatPage = this.page(page, wrapper);

        // 转换为VO
        Page<YunkeChatVo> result = new Page<>();
        result.setCurrent(chatPage.getCurrent());
        result.setSize(chatPage.getSize());
        result.setTotal(chatPage.getTotal());
        
        List<YunkeChatVo> chatVoList = new ArrayList<>();
        for (YunkeUserChat chat : chatPage.getRecords()) {
            YunkeChatVo chatVo = convertToChatVo(chat, currentUserId);
            if (chatVo != null) {
                chatVoList.add(chatVo);
            }
        }
        result.setRecords(chatVoList);

        log.info("获取聊天列表成功，用户ID：{}，数量：{}", currentUserId, chatVoList.size());
        return result;
    }

    @Override
    public Page<YunkeMessageVo> getChatHistory(String chatId, Long current, Long size) {
        // 检查登录状态
        if (!StpUtil.isLogin()) {
            throw new YunkeException("请先登录");
        }

        Long currentUserId = StpUtil.getLoginIdAsLong();
        
        // 验证聊天室权限
        YunkeUserChat chat = getChatByIdAndUserId(chatId, currentUserId);
        if (chat == null) {
            throw new YunkeException("聊天室不存在或无权限访问");
        }

        log.info("获取聊天记录，聊天室ID：{}，用户ID：{}", chatId, currentUserId);

        // 分页查询消息记录
        Page<YunkeUserMessage> page = new Page<>(current, size);
        LambdaQueryWrapper<YunkeUserMessage> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(YunkeUserMessage::getChatId, chatId)
                .orderByDesc(YunkeUserMessage::getSendTime);

        Page<YunkeUserMessage> messagePage = userMessageMapper.selectPage(page, wrapper);

        // 转换为VO
        Page<YunkeMessageVo> result = new Page<>();
        result.setCurrent(messagePage.getCurrent());
        result.setSize(messagePage.getSize());
        result.setTotal(messagePage.getTotal());
        
        List<YunkeMessageVo> messageVoList = new ArrayList<>();
        for (YunkeUserMessage message : messagePage.getRecords()) {
            YunkeMessageVo messageVo = convertToMessageVo(message, currentUserId);
            if (messageVo != null) {
                messageVoList.add(messageVo);
            }
        }
        result.setRecords(messageVoList);

        log.info("获取聊天记录成功，聊天室ID：{}，消息数量：{}", chatId, messageVoList.size());
        return result;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public YunkeMessageVo sendMessage(YunkeSendMessageDto sendMessageDto) {
        // 检查登录状态
        if (!StpUtil.isLogin()) {
            throw new YunkeException("请先登录");
        }

        Long currentUserId = StpUtil.getLoginIdAsLong();
        log.info("发送消息，发送者：{}，接收者：{}", currentUserId, sendMessageDto.getReceiverId());

        // 验证接收者是否存在
        YunkeUser receiver = userService.getById(sendMessageDto.getReceiverId());
        if (receiver == null) {
            throw new YunkeException("接收者不存在");
        }

        // 验证消息内容
        validateMessageContent(sendMessageDto);

        // 获取或创建聊天室
        String chatId = getOrCreateChatRoom(currentUserId, sendMessageDto.getReceiverId());

        // 创建消息
        YunkeUserMessage message = createMessage(chatId, currentUserId, sendMessageDto);
        userMessageMapper.insert(message);

        // 更新聊天室最后一条消息
        updateChatLastMessage(chatId, message);

        // 转换为VO返回
        YunkeMessageVo messageVo = convertToMessageVo(message, currentUserId);

        log.info("发送消息成功，消息ID：{}", message.getMessageId());
        return messageVo;
    }

    // TODO: 实现其他接口方法
    @Override
    public YunkeMessageVo sendImageMessage(Long receiverId, MultipartFile imageFile, String replyMessageId) {
        // TODO: 实现图片消息发送
        throw new YunkeException("功能开发中");
    }

    @Override
    public YunkeMessageVo sendVoiceMessage(Long receiverId, MultipartFile voiceFile, Integer duration, String replyMessageId) {
        // TODO: 实现语音消息发送
        throw new YunkeException("功能开发中");
    }

    @Override
    public YunkeMessageVo sendLocationMessage(Long receiverId, Double longitude, Double latitude, String address, String replyMessageId) {
        // TODO: 实现位置消息发送
        throw new YunkeException("功能开发中");
    }

    @Override
    public boolean markMessagesAsRead(String chatId, List<String> messageIds) {
        // TODO: 实现标记消息已读
        log.info("标记消息已读，聊天室ID：{}，消息数量：{}", chatId, messageIds.size());
        return true;
    }

    @Override
    public boolean deleteChatRecord(String chatId, Integer deleteType, List<String> messageIds) {
        // TODO: 实现删除聊天记录
        log.info("删除聊天记录，聊天室ID：{}，删除类型：{}", chatId, deleteType);
        return true;
    }

    @Override
    public boolean setChatTop(String chatId, Boolean isTop) {
        // TODO: 实现设置聊天置顶
        log.info("设置聊天置顶，聊天室ID：{}，置顶：{}", chatId, isTop);
        return true;
    }

    @Override
    public boolean setChatMute(String chatId, Boolean isMute) {
        // TODO: 实现设置消息免打扰
        log.info("设置消息免打扰，聊天室ID：{}，免打扰：{}", chatId, isMute);
        return true;
    }

    @Override
    public Map<String, Object> checkUserInfoApply(YunkeCheckUserInfoDto checkUserInfoDto) {
        // TODO: 实现查看用户信息申请
        Map<String, Object> result = new HashMap<>();
        result.put("success", false);
        result.put("message", "功能开发中");
        return result;
    }

    @Override
    public Map<String, Object> getUnreadCount() {
        // TODO: 实现获取未读消息数
        Map<String, Object> result = new HashMap<>();
        result.put("totalUnread", 0);
        result.put("chatUnread", new ArrayList<>());
        return result;
    }

    @Override
    public Page<YunkeMessageVo> searchChatHistory(String chatId, String keyword, Integer messageType, Long current, Long size) {
        // TODO: 实现搜索聊天记录
        return new Page<>();
    }

    @Override
    public boolean recallMessage(String messageId, String reason) {
        // TODO: 实现撤回消息
        log.info("撤回消息，消息ID：{}，原因：{}", messageId, reason);
        return true;
    }

    @Override
    public boolean connectWebSocket(Long userId, String sessionId) {
        // TODO: 实现WebSocket连接
        log.info("建立WebSocket连接，用户ID：{}，会话ID：{}", userId, sessionId);
        return true;
    }

    @Override
    public boolean disconnectWebSocket(Long userId, String sessionId) {
        // TODO: 实现WebSocket断开
        log.info("断开WebSocket连接，用户ID：{}，会话ID：{}", userId, sessionId);
        return true;
    }

    @Override
    public Map<String, Object> initiateCall(Long receiverId, Integer callType) {
        // TODO: 实现发起语音通话
        Map<String, Object> result = new HashMap<>();
        result.put("success", false);
        result.put("message", "功能开发中");
        return result;
    }

    @Override
    public boolean respondCall(String callId, Integer action) {
        // TODO: 实现响应语音通话
        log.info("响应语音通话，通话ID：{}，动作：{}", callId, action);
        return true;
    }

    /**
     * 转换为聊天VO
     */
    private YunkeChatVo convertToChatVo(YunkeUserChat chat, Long currentUserId) {
        try {
            YunkeChatVo chatVo = new YunkeChatVo();
            chatVo.setChatId(chat.getChatId());
            chatVo.setChatTypeText(getChatTypeText(chat.getChatType()));
            chatVo.setLastMessage(chat.getLastMessage());
            chatVo.setLastMessageTypeText(getMessageTypeText(chat.getLastMessageType()));
            chatVo.setLastMessageTime(chat.getLastMessageTime());
            chatVo.setLastMessageTimeText(formatTimeToText(chat.getLastMessageTime()));
            chatVo.setIsMyLastMessage(Objects.equals(chat.getLastMessageSenderId(), currentUserId));
            chatVo.setStatusText(getChatStatusText(chat.getStatus()));
            
            // 设置对方用户信息和个人设置
            Long otherUserId = Objects.equals(chat.getUserAId(), currentUserId) ? chat.getUserBId() : chat.getUserAId();
            YunkeChatVo.UserInfo otherUser = buildUserInfo(otherUserId);
            chatVo.setOtherUser(otherUser);
            
            // 设置个人设置
            if (Objects.equals(chat.getUserAId(), currentUserId)) {
                chatVo.setUnreadCount(chat.getUserAUnreadCount());
                chatVo.setIsTop(chat.getUserAIsTop() == 1);
                chatVo.setIsMute(chat.getUserAIsMute() == 1);
            } else {
                chatVo.setUnreadCount(chat.getUserBUnreadCount());
                chatVo.setIsTop(chat.getUserBIsTop() == 1);
                chatVo.setIsMute(chat.getUserBIsMute() == 1);
            }

            return chatVo;
        } catch (Exception e) {
            log.error("转换聊天VO失败", e);
            return null;
        }
    }

    /**
     * 转换为消息VO
     */
    private YunkeMessageVo convertToMessageVo(YunkeUserMessage message, Long currentUserId) {
        try {
            YunkeMessageVo messageVo = new YunkeMessageVo();
            messageVo.setMessageId(message.getMessageId());
            messageVo.setChatId(message.getChatId());
            messageVo.setMessageType(message.getMessageType());
            messageVo.setMessageTypeText(getMessageTypeText(message.getMessageType()));
            messageVo.setContent(message.getContent());
            messageVo.setMediaUrl(message.getMediaUrl());
            messageVo.setVoiceDuration(message.getVoiceDuration());
            messageVo.setStatus(message.getStatus());
            messageVo.setStatusText(getMessageStatusText(message.getStatus()));
            messageVo.setIsRead(message.getIsRead() == 1);
            messageVo.setReadTime(message.getReadTime());
            messageVo.setIsRecall(message.getIsRecall() == 1);
            messageVo.setRecallTime(message.getRecallTime());
            messageVo.setSendTime(message.getSendTime());
            messageVo.setSendTimeText(formatTimeToText(message.getSendTime()));
            messageVo.setIsMine(Objects.equals(message.getSenderId(), currentUserId));

            // 设置发送者和接收者信息
            YunkeMessageVo.UserInfo sender = buildSimpleUserInfo(message.getSenderId());
            YunkeMessageVo.UserInfo receiver = buildSimpleUserInfo(message.getReceiverId());
            messageVo.setSender(sender);
            messageVo.setReceiver(receiver);

            // 设置位置信息
            if (message.getMessageType() == 4) {
                YunkeMessageVo.LocationInfo location = new YunkeMessageVo.LocationInfo();
                location.setLongitude(message.getLongitude());
                location.setLatitude(message.getLatitude());
                location.setAddress(message.getLocationAddress());
                messageVo.setLocation(location);
            }

            // 设置回复信息
            if (StrUtil.isNotBlank(message.getReplyMessageId())) {
                YunkeMessageVo.ReplyInfo replyInfo = new YunkeMessageVo.ReplyInfo();
                replyInfo.setReplyMessageId(message.getReplyMessageId());
                replyInfo.setReplyContent(message.getReplyContent());
                messageVo.setReplyInfo(replyInfo);
            }

            return messageVo;
        } catch (Exception e) {
            log.error("转换消息VO失败", e);
            return null;
        }
    }

    /**
     * 获取或创建聊天室
     */
    private String getOrCreateChatRoom(Long userAId, Long userBId) {
        // 查找已存在的聊天室
        LambdaQueryWrapper<YunkeUserChat> wrapper = new LambdaQueryWrapper<>();
        wrapper.and(w -> w.and(w1 -> w1.eq(YunkeUserChat::getUserAId, userAId)
                .eq(YunkeUserChat::getUserBId, userBId))
                .or(w2 -> w2.eq(YunkeUserChat::getUserAId, userBId)
                .eq(YunkeUserChat::getUserBId, userAId)))
                .eq(YunkeUserChat::getChatType, 1);

        YunkeUserChat existChat = this.getOne(wrapper);
        if (existChat != null) {
            return existChat.getChatId();
        }

        // 创建新聊天室
        String chatId = "chat_" + IdUtil.fastSimpleUUID();
        YunkeUserChat newChat = new YunkeUserChat();
        newChat.setChatId(chatId);
        newChat.setUserAId(userAId);
        newChat.setUserBId(userBId);
        newChat.setChatType(1); // 单聊
        newChat.setStatus(1); // 正常
        newChat.setUserAUnreadCount(0);
        newChat.setUserBUnreadCount(0);
        newChat.setUserAIsTop(0);
        newChat.setUserBIsTop(0);
        newChat.setUserAIsMute(0);
        newChat.setUserBIsMute(0);
        newChat.setCreateTime(System.currentTimeMillis());
        newChat.setUpdateTime(System.currentTimeMillis());

        this.save(newChat);
        log.info("创建新聊天室成功，聊天室ID：{}", chatId);
        return chatId;
    }

    // 其他工具方法...
    private void validateMessageContent(YunkeSendMessageDto dto) {
        if (dto.getMessageType() == 1 && StrUtil.isBlank(dto.getContent())) {
            throw new YunkeException("文字消息内容不能为空");
        }
        // TODO: 其他消息类型验证
    }

    private YunkeUserMessage createMessage(String chatId, Long senderId, YunkeSendMessageDto dto) {
        YunkeUserMessage message = new YunkeUserMessage();
        message.setMessageId("msg_" + IdUtil.fastSimpleUUID());
        message.setChatId(chatId);
        message.setSenderId(senderId);
        message.setReceiverId(dto.getReceiverId());
        message.setMessageType(dto.getMessageType());
        message.setContent(dto.getContent());
        message.setMediaUrl(dto.getMediaUrl());
        message.setVoiceDuration(dto.getVoiceDuration());
        message.setLongitude(dto.getLongitude());
        message.setLatitude(dto.getLatitude());
        message.setLocationAddress(dto.getLocationAddress());
        message.setReplyMessageId(dto.getReplyMessageId());
        message.setExtraData(dto.getExtraData());
        message.setStatus(2); // 已发送
        message.setIsRead(0);
        message.setIsRecall(0);
        message.setSendTime(System.currentTimeMillis());
        message.setCreateTime(System.currentTimeMillis());
        message.setUpdateTime(System.currentTimeMillis());
        return message;
    }

    private void updateChatLastMessage(String chatId, YunkeUserMessage message) {
        // TODO: 更新聊天室最后一条消息信息
    }

    private YunkeUserChat getChatByIdAndUserId(String chatId, Long userId) {
        // TODO: 验证聊天室权限
        return null;
    }

    private YunkeChatVo.UserInfo buildUserInfo(Long userId) {
        // TODO: 构建用户信息
        return new YunkeChatVo.UserInfo();
    }

    private YunkeMessageVo.UserInfo buildSimpleUserInfo(Long userId) {
        // TODO: 构建简单用户信息
        return new YunkeMessageVo.UserInfo();
    }

    private String getChatTypeText(Integer chatType) {
        return chatType == 1 ? "单聊" : "群聊";
    }

    private String getMessageTypeText(Integer messageType) {
        switch (messageType) {
            case 1: return "文字";
            case 2: return "图片";
            case 3: return "语音";
            case 4: return "位置";
            case 5: return "系统消息";
            default: return "未知";
        }
    }

    private String getChatStatusText(Integer status) {
        switch (status) {
            case 1: return "正常";
            case 2: return "已删除";
            case 3: return "已屏蔽";
            default: return "未知";
        }
    }

    private String getMessageStatusText(Integer status) {
        switch (status) {
            case 1: return "发送中";
            case 2: return "已发送";
            case 3: return "已送达";
            case 4: return "已读";
            case 5: return "发送失败";
            case 6: return "已撤回";
            default: return "未知";
        }
    }

    private String formatTimeToText(Long timestamp) {
        if (timestamp == null) {
            return "";
        }
        long now = System.currentTimeMillis();
        long diff = now - timestamp;
        
        if (diff < 60000) { // 1分钟内
            return "刚刚";
        } else if (diff < 3600000) { // 1小时内
            return (diff / 60000) + "分钟前";
        } else if (diff < 86400000) { // 24小时内
            return (diff / 3600000) + "小时前";
        } else {
            return (diff / 86400000) + "天前";
        }
    }
} 